import fs from 'fs'
import inquirer from "inquirer"; // 命令行交互工具，可以实现命令行的选择功能，输入功能
import chalk from "chalk"; // 颜色
import ora from 'ora'
import { projectTypeList, templateList } from "../config/index";
import { downloadTemplate } from '../util/index'

export async function create(projectName: string) {
  const isExist = fs.existsSync(`./${projectName}`);
  if (isExist) {
    // 判断路径是否存在，存在抛出错误
    console.log("~ " + chalk.red(`${projectName} 项目已存在`));
    return
  }
  const inputContent = await inquirer.prompt([
    { type: 'input', message: "请输入项目作者", name: 'author', default: '' },
    { type: 'input', message: "请输入项目版本", name: 'version', default: '1.0.0' },
    { type: 'input', message: "请输入项目描述", name: 'description', default: '' },
  ])
  const projectType = await selectProjectType(); // 选中的项目类型
  const projectTemplate = await selectProjectTemplate(projectType) // 选中的项目模版
  const templateInfo: any = templateList.find((item) => item.type === projectType && item.name === projectTemplate)
  const downloadSpinner = ora({ text: '开始下载模版', color: 'blue' }).start();

  const { state, name, dir, message, } = await downloadTemplate({ templateInfo, projectName })
  if (state === 1) {
    downloadSpinner.fail(message)
    downloadSpinner.stop
    return console.log("~ " + chalk.red(projectName + '项目模版下载失败'))
  }
  if (state === 2) {
    // 项目模版下载成功
    downloadSpinner.succeed(message)
    const { readStatus, readData } = await readFilePackageJson(dir) // 读取返回的结果
    downloadSpinner.stop
    if (!readStatus) return downloadSpinner.fail('fs.readFile :=> 读取文件失败！')
    const packageFile = { ...JSON.parse(readData), ...inputContent, name }
    const { writeStatus } = await writeFilePackageJson(dir, packageFile) // 是否写入成功
    if (!writeStatus) {
      return downloadSpinner.fail('fs.writeFile :=> 写入文件失败！')
    }

    const scripts = `cd ./${projectName} && npm install`;
    console.log("🚀🚀 ~ " + chalk.blue(`${scripts}`));
    console.log("🚀🚀 ~ " + chalk.blue("npm run dev"));
  }
}

// 选择项目类型
async function selectProjectType(): Promise<string> {
  const data = [{ type: "list", message: "项目类型选择", name: "projectType", choices: projectTypeList }]
  const result = await inquirer.prompt(data)
  return result.projectType
}
// 选择项目模版
async function selectProjectTemplate(projectType: string) {
  const list = templateList.filter((item) => item.type === projectType)
  const data = [{ type: 'list', message: '选择项目模版', name: 'projectTemplate', choices: list }]
  const result = await inquirer.prompt(data)
  return result.projectTemplate
}

// 读取 package.json
function readFilePackageJson(dir: string): Promise<{ readStatus: boolean, readData: string }> {
  return new Promise((resolve, reject) => {
    fs.readFile(dir + '/package.json', 'utf8', (err, data) => {
      if (err) {
        resolve({ readStatus: false, readData: '' })
      } else {
        resolve({ readStatus: true, readData: data })
      }
    })
  })
}
// 写入 package.json
function writeFilePackageJson(dir: string, packageFile: any): Promise<{ writeStatus: boolean }> {
  return new Promise((resolve, reject) => {
    fs.writeFile(dir + '/package.json', JSON.stringify(packageFile, null, 4), 'utf8', (err) => {
      if (err) {
        resolve({ writeStatus: false })
      } else {
        resolve({ writeStatus: true })
      }
    })
  })
}